package com.authstr.support;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 对两个集合进行比较的工具
 */
public class CompareTool {
    /**
     * 关键字 分隔符
     */
    public static  final String KEYWORD_SPLIT=",";

    public static CompareResult  compare(List<Map<String,Object>> newData,List<Map<String,Object>> oldDate, String...uniqueColumn){
        //将List<Map>转换Map,其中唯一键的值作为key
        Map<String,Map> newMapDate=listToMapByUniqueColumn(newData,uniqueColumn);
        Map<String,Map> oldMapDate=listToMapByUniqueColumn(oldDate,uniqueColumn);

        CompareResult result=new CompareResult(uniqueColumn);
        result.setNewDate(newMapDate);
        result.setOldDate(oldMapDate);

        //取出Map的Key
        Set<String> newSet = newMapDate.keySet();
        Set<String> oldSet = oldMapDate.keySet();



        //获取新减旧的差集
        Set<String> newSubtractOld=new HashSet<String>();
        newSubtractOld.addAll(newSet);
        newSubtractOld.removeAll(oldSet);
        result.setNewSubtractOld(new ArrayList<>(newSubtractOld));


        //获取旧减新的差集
        Set<String> oldSubtractNew=new HashSet<String>();
        oldSubtractNew.addAll(oldSet);
        oldSubtractNew.removeAll(newSet);
        result.setOldSubtractNew(new ArrayList<>(oldSubtractNew));

        //获取新和旧的交集
        Set<String> intersection=new HashSet<String>();
        intersection.addAll(oldSet);
        intersection.retainAll(newSet);
        result.setIntersection(new ArrayList<>(intersection));

        return result;
    }

    /**
     * 对CompareResult里的数据进行比较,判断并集里那些是实际需要生成更新sql语句的
     * @param result
     */
    public static void compareGetUpdateData(CompareResult result){
        List<String> intersection=result.getIntersection();
        //判断并集至少有一个数据
        if(intersection.isEmpty()){
            result.setActualNeedUpdateColumn(new ArrayList<>());
            return;
        }
        //随便取出一个数据,用于获取字段列
        Map<String,Object> tempData=result.getNewDate().get(intersection.get(0));

        //获取需要更新的字段
        Set<String> updateColumn=new HashSet<String>();
        updateColumn.addAll(tempData.keySet());
        updateColumn.removeAll(new HashSet<>(Arrays.asList(result.getUpdateIgnoreColumn())));

        result.setActualNeedUpdateColumn(new ArrayList<>(updateColumn));

        List<String> actualNeedUpdateValue=new ArrayList<>();
        for(int i=0;i<intersection.size();i++){
            String key=intersection.get(i);
            Map<String,Object> newData=result.getNewDate().get(key);
            Map<String,Object> oldData=result.getOldDate().get(key);
            Boolean isSame=compareIsCompleteSame(result.getActualNeedUpdateColumn(),newData,oldData);
            if(!isSame){
                actualNeedUpdateValue.add(key);
            }
        }
        result.setActualNeedUpdateValue(actualNeedUpdateValue);
    }

    /**
     * 用于比较两个Map数据在指定的列上是否完全一致
     * @param compareColumn
     * @param newData
     * @param oldData
     * @return
     */
    public static Boolean compareIsCompleteSame(List<String> compareColumn, Map<String,Object> newData,Map<String,Object> oldData){
        for(int i=0;i<compareColumn.size();i++){
            Object newValue=newData.get(compareColumn.get(i));
            Object oldValue=oldData.get(compareColumn.get(i));
            if(null==newValue){
                if(null!=oldValue){
                    return false;
                }
            }else{
                if(!newValue.equals(oldValue)){
                    return false;
                }
            }

        }
        return true;
    }



    /**
     * 将List<Map>转换为一个Map,其中键是唯一列
     * @param list
     * @param uniqueColumn
     * @return
     */
    public static Map<String,Map> listToMapByUniqueColumn(List<Map<String,Object>> list,String...uniqueColumn){
        Map<String,Map> map=new HashMap<String,Map>();
        for(int i=0;i<list.size();i++){
            Map<String,Object> temp=list.get(i);
            List<String> map_value=new ArrayList<>();

            //取出每个列对应的值
            for(int j=0;j<uniqueColumn.length;j++){
                Object value=temp.get(uniqueColumn[j]);
                map_value.add(value!=null?value.toString():"");
            }

            //将值转换为 , 分割的字符串
            String merge = "";
            for(int z=0;z<map_value.size();z++){
                merge=merge+map_value.get(z);
                if(z!=0&&z==(map_value.size()-1)){
                    merge=merge+KEYWORD_SPLIT;
                }
            }
            map.put(merge,temp);

        }
        return map;
    }

    /**
     * 从listMap获取指定键的值,作为set返回
     * @param list
     * @param uniqueColumn
     * @return
     */
    public static Set<String> listMapGetKeyValueToSet(List<Map<String,Object>> list,String...uniqueColumn){
        Set<String> set = new HashSet<String>();
        for(int i=0;i<list.size();i++){
            Map<String,Object> temp=list.get(i);
            List<String> map_value=new ArrayList<>();
            //取出每个列对应的值
            for(int j=0;j<uniqueColumn.length;j++){
                Object value=temp.get(uniqueColumn[j]);
                map_value.add(value!=null?value.toString():"");
            }

            //将值转换为 , 分割的字符串
            String merge = "";
            for(int z=0;z<map_value.size();z++){
                merge=merge+map_value.get(z);
                if(z!=0&&z==(map_value.size()-1)){
                    merge=merge+KEYWORD_SPLIT;
                }
            }
            set.add(merge);
        }
        return set;
    }

}
